home *** CD-ROM | disk | FTP | other *** search
- ;void justify_line(input_strg,return_string,remainder,line_len)
- ; char *input_strg,*return_string,*remainder;
- ; int line_len;
-
- EXTRN _memory_model:byte
- EXTRN _remainder:byte
-
- _TEXT SEGMENT BYTE PUBLIC 'CODE'
- ASSUME CS:_TEXT
- PUBLIC _justify_line
- _justify_line proc near
- push bp
- mov bp,sp
- push di
- push si
- push ds
- cmp _memory_model,0 ;near or far?
- jle begin ;jump if near
- inc bp ;else add 2 to BP
- inc bp ;
- begin: jmp short Z2 ;jump over data
- remainder_seg dw ?
- remainder_ofs dw ?
- return_seg dw ?
- return_ofs dw ?
- num_write db ?
- extra_space db ?
- line_len dw ?
- Z2: cmp _memory_model,2 ;data near or far?
- jb Y2 ;jump if near
- les di,dword ptr[bp+8] ;ES:DI pts to return string
- lds bx,dword ptr[bp+12] ;point DS:BX to remainder
- mov cs:remainder_seg,ds ;save for later
- mov cs:remainder_ofs,bx ;
- mov byte ptr ds:[bx],0 ;return null in remainder if error
- lds si,dword ptr[bp+4] ;point DS:SI to Strg
- mov ax,[bp+16] ;line_len value to AX
- jmp short X2 ;jump ahead
- Y2: mov ax,ds ;NEAR case
- mov es,ax ;
- mov di,[bp+6] ;
- mov bx,[bp+8] ;
- mov cs:remainder_seg,ds ;save for later
- mov cs:remainder_ofs,bx ;
- mov byte ptr ds:[bx],0 ;return null in remainder if error
- mov si,[bp+4] ;
- mov ax,[bp+10] ;
- X2: mov byte ptr es:[di],0 ;return null in return_strg if error
- mov cs:return_seg,es ;keep address for later
- mov cs:return_ofs,di ;
- mov cs:line_len,ax ;keep line length for later
- or ax,ax ;test for null line_length
- jz U2 ;quit if null
- push si ;get length of input string
- sub cx,cx ;clear CX
- W2: cmp byte ptr[si],0 ;
- je V2 ;
- inc cx ;
- inc si ;
- jmp short W2 ;
- V2: pop si ;
- dec si ;
- or cx,cx ;test if null input
- jnz B1 ;
- U2: jmp B2 ;quit if null
- B1: cmp byte ptr[si+1],32 ;nxt char a space?
- jne D1 ;jump ahead if not
- cmp byte ptr[si+3],32 ;3rd char a space?
- jne C1 ;jump ahead if not
- cmp byte ptr[si+2],32 ;2nd char a space?
- je D1 ;don't del spcs if so
- C1: dec cl ;dec string len ctr
- inc si ;forward BP to elim char
- jmp short B1 ;go check for another spc
- D1: mov dx,cx ;copy strg len to DX
- sub bx,bx ;use BX as ptr to string
- E1: inc bx ;forward string pointer
- cmp byte ptr[bx][si],128 ;high end of codes
- jb F1 ;jump if not ctrl code
- cmp byte ptr[bx][si],159 ;low end of codes
- ja F1 ;jump if not ctrl code
- dec dx ;dec string length ctr
- F1: loop E1 ;go count next char
- push bx ;save string length
- cmp dx,ax ;cmp strg len to linelen
- ja G1 ;jump ahead if longer
- pop cx ;balance stack for jmp
- mov cx,bx ;mov string len to CX
- sub ax,ax ;AX=0 flags short string
- jmp short N1 ;go set string for return
- G1: mov cx,ax ;linelen to CX
- sub ax,ax ;AX holds spc positions
- sub dh,dh ;clear DH to count spaces
- inc cx ;count one further
- sub bx,bx ;pt SI to start of strg
- H1: inc bx ;forward string pointer
- cmp byte ptr[bx][si],128 ;low end of codes
- jb I1 ;jump ahead if not
- cmp byte ptr[bx][si],159 ;high end of codes
- ja I1 ;jump ahead if not
- jmp short H1 ;else don't count it
- I1: cmp byte ptr[bx][si],32 ;spc char?
- jne J1 ;jump ahead if not
- mov ax,bx ;else save spc position
- inc dh ;inc count of spaces
- J1: loop H1 ;go do next char in strg
- cmp ax,0 ;no spaces at all?
- je K1 ;jump ahead if so
- mov bx,ax ;point SI to last spc
- jmp short L1 ;jump ahead
- K1: mov ax,bx ;set string pointer
- dec bx ;set back 1
- L1: pop cx ;string length to CX
- sub cx,bx ;remainder length
- push ax ;point ES:DI to remainder
- mov ax,cs:remainder_seg ;point to remainder
- mov es,ax ;
- mov di,cs:remainder_ofs ;
- pop ax ;
- inc bx ;remainder ptr to 1st chr
- dec di ;adjust for loop ahead
- M1: inc di ;forward remainder ptr
- mov dl,[bx][si] ;get char from end of str
- mov es:[di],dl ;place in remainder
- inc bx ;forward string ptr
- loop M1 ;go get next char
- mov cx,ax ;return string length
- dec cx ;adjust
- N1: sub bx,bx ;clear string pointer
- or ax,ax ;test for zero length
- jnz P1 ;skip loop if zero
- dec di ;adjust for loop ahead
- O1: inc bx ;forward strg ptr
- inc di ;forward return ptr
- mov dl,[bx][si] ;get char from strg
- mov es:[di],dl ;set it for return
- loop O1 ;go get next char
- mov byte ptr es:[di+2],0 ;set terminator
- jmp B2 ;quit routine
- P1: dec dh ;adjust num spc positions
- mov dl,dh ;move to DL
- sub dh,dh ;DX holds num spc pos
- mov ax,cs:line_len ;fetch line length
- push cx ;save string length
- Q1: inc bx ;for ea byte of string..
- cmp byte ptr[bx][si],128 ;low end of codes
- jb R1 ;jump ahead if not code
- cmp byte ptr[bx][si],159 ;high end of codes
- ja R1 ;jump ahead if not code
- inc ax ;else inc ctrl code ctr
- R1: loop Q1 ;go check next char
- pop cx ;restore string length
- mov di,ax ;DI=LineLen+num ctrl codes
- sub di,cx ;DI=num extra spaces
- S1: cmp di,dx ;div by num spc positions
- jb T1 ;leave loop when finished
- inc ah ;inc result
- sub di,dx ;adjust dividend
- jmp short S1 ;loop
- T1: mov bx,di ;make high and low available
- push ax ;for ES:DI to return string
- mov ax,cs:return_seg ;
- mov es,ax ;
- mov di,cs:return_ofs ;
- pop ax ;
- dec di ;
- mov bh,ah ;num spc to add at ea pos
- mov dh,bl ;copy remainder to DH
- sub dl,bl ;spc positions-remainder
- mov bl,dl ;num pos to NOT wrt extra
- mov al,dh ;copy remainder in AL
- shr dh,1 ;divide remainder by 2
- sub al,dh ;(AL=right)
- mov cs:num_write,bh ;save values
- mov cs:extra_space,bl ;
- sub bx,bx ;pointer back to start of string
- U1: inc bx ;forward string ptr
- inc di ;forward return strg ptr
- mov dl,[bx][si] ;get char from string
- cmp dl,32 ;check for space char
- jne A2 ;jump ahead if not spc
- V1: or ah,ah ;AH=extra spc at each pos
- jz W1 ;jump ahead if none
- dec ah ;else count down
- mov es:[di],dl ;write a space
- inc di ;forward ret strg ptr
- jmp short V1 ;go chk for another
- W1: mov ah,cs:num_write ;
- or dh,dh ;DL=extra spc on left
- jz X1 ;jump ahead if done
- dec dh ;else dec left spc ctr
- jmp short Y1 ;go write the extra space
- X1: cmp byte ptr cs:extra_space,0
- jne Z1 ;
- Y1: mov es:[di],dl ;else write spc on right
- inc di ;forward string ptr
- jmp short A2 ;jump ahead
- Z1: dec cs:extra_space ;dec extra space counter
- A2: mov es:[di],dl ;set it for return
- loop U1 ;go do next char
- B2: pop ds ;
- pop si ;
- pop di ;
- pop bp ;
- cmp _memory_model,0 ;quit
- jle quit ;
- db 0CBh ;RET far
- quit: ret ;RET near
- _justify_line endp
- _TEXT ENDS
- END